﻿using DroidClaim.BL.Dto;
using DroidClaim.BL.Helper;
using DroidClaim.BL.Utility;
using DroidClaim.Service;
using DroidClaim.Service.Dto;
using DroidClaimBL.Dto;
using FluentNHibernate.Automapping;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using log4net;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Text;
using System.Web.Script.Serialization;

namespace DroidClaim.BL
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "DroidClaimBL" in code, svc and config file together.
    // NOTE: In order to launch WCF Test Client for testing this service, please select DroidClaimBL.svc or DroidClaimBL.svc.cs at the Solution Explorer and start debugging.
    //[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class DroidClaimBL : IDroidClaimBL
    { 
        ILog logger;
        /*private readonly ISession _session;
        private readonly ISessionFactory _sessionFactory;

        public DroidClaimBL()
        {
            var appReader = new System.Configuration.AppSettingsReader();
            var connectionString = Convert.ToString(appReader.GetValue("connectionString", typeof(string)));
            var mappingScriptPath = AppDomain.CurrentDomain.BaseDirectory + "/db_mappings";
            if (!Directory.Exists(mappingScriptPath))
                Directory.CreateDirectory(mappingScriptPath);

            _sessionFactory = Fluently.Configure()
                .Database(
                    MsSqlConfiguration.MsSql2008
                    .ConnectionString(@connectionString))
                    .Mappings(x => x.AutoMappings.Add(AutoMap.AssemblyOf<DroidClaim.Service. ClaimInfo>().Where(t => t.Namespace != null && t.Namespace.EndsWith("Entities"))).ExportTo(@mappingScriptPath))
                    //.ExposeConfiguration(BuildSchema) // ********** ใช้ครั้งแรกเท่านั้น (กรณียังไม่มี Table)
                    .BuildSessionFactory();
            _session = _sessionFactory.OpenSession();
        }

        private void BuildSchema(Configuration config)
        {
            new SchemaExport(config).Create(false, true);
        }*/

        public ResultBlDto RegisterCustomer(RegisterCustomerBlDto blDto)
        {
            ResultBlDto result = new ResultBlDto();
            result.Result = false;
            try
            {
                Service.Dto.CustomerDto svDto = blDto.ToServiceDto();
                var deriveBytes = new Rfc2898DeriveBytes(svDto.Password, 20);
                byte[] salt = deriveBytes.Salt;
                byte[] key = deriveBytes.GetBytes(20);
                svDto.Salt = Convert.ToBase64String(salt);
                svDto.Password = Convert.ToBase64String(key);

                IService dcService = new DroidClaim.Service.Service();              
                dcService.AddCustomer(svDto);
                result.Result = true;
            }
            catch (Exception ex)
            {
                result.ErrorMsg = ex.Message;
            }

            return result;
        }

        /*
            public class AuthenCustomerDto
            {
                public string LicensePlate { get; set; }
                public string Password { get; set; }
                public String RregistrationId { get; set; }
            }
            
            public class AuthenCustomerResultDto
            {
                public bool Result { get; set; }
                public string ErrorMsg { get; set; }
                public string SessionId { get; set; }
                public CustomerDto customerInfo { get; set; }
            }
         
         */
        public AuthenCustomerResultBlDto AuthenCustomer(AuthenCustomerBlDto authenCustomer)
        {
            AuthenCustomerResultBlDto result = new AuthenCustomerResultBlDto();
            result.Result = false;
         
            try
            {
                // get data by using Licenseplate 
                IService service = new DroidClaim.Service.Service();
                GetAllCustomerRequestDto svDto = new GetAllCustomerRequestDto();
                svDto.LicensePlate = authenCustomer.LicensePlate;
                ResponseDto<List<Service.Dto.CustomerDto>> svResultDto = service.GetAllCustomer(svDto);
                if(!svResultDto.Status){
                    throw new InvalidOperationException("Operation is invalid.");
                }

                // Validate result's data is not error
                List<Service.Dto.CustomerDto> svDataListDto = svResultDto.Data;
                if (svDataListDto.Count <= 0)
                {
                    throw new Exception("Username or Password is invalid.");
                }
                Service.Dto.CustomerDto svDataDto =  svResultDto.Data[0];
                if (svDataDto == null)
                {
                    throw new Exception("Invalid return data");
                }

                // do authenticate whether it is correct or not
                byte[] saltByte = Convert.FromBase64String(svDataDto.Salt);
                var deriveBytes = new Rfc2898DeriveBytes(authenCustomer.Password, saltByte);
                byte[] inputPassByte = deriveBytes.GetBytes(20);  // derive a 20-byte key
                byte[] userPassByte = Convert.FromBase64String(svDataDto.Password);
                if (!userPassByte.SequenceEqual(inputPassByte))
                {
                    throw new InvalidOperationException("Username or Password is invalid!");
                }

                // delete invalidate seesion of this Customer
                GetAllSessionInfoRequestDto svGetSessionDto = new GetAllSessionInfoRequestDto();
                svGetSessionDto.Customer = svDataDto;
                ResponseDto<List<SessionInfoDto>> svResultGetSessionDto = service.GetAllSessionInfo(svGetSessionDto);
                if (!svResultGetSessionDto.Status)
                {
                    throw new InvalidOperationException("Operation Error"); 
                }
                List<SessionInfoDto> sessionList = svResultGetSessionDto.Data;
                if(sessionList==null){
                    throw new InvalidOperationException("Data Error"); 
                }
                if(sessionList.Count>0){
                    List<string> idList = new List<string>();
                    foreach (SessionInfoDto session in sessionList)
                    {
                        idList.Add(session.SessionId);
                    }
                    service.DeleteSessionInfo(idList);
                }

                // create session
                SessionInfoDto sessionInfo = new SessionInfoDto();
                sessionInfo.UpdateTime = DateTime.Now;
                sessionInfo.SessionId = Guid.NewGuid().ToString();
				sessionInfo.Surveyor = null;
				sessionInfo.Customer = svDataDto;
                sessionInfo.RegistrationId = authenCustomer.RegistrationId;
                service.AddSessionInfo(sessionInfo);

                // it's ok, so return result
                result.Result = true;
                result.ErrorMsg = null;
                result.SessionId = sessionInfo.SessionId;
                result.CustomerInfo = new CustomerBlDto(svDataDto);

            }
            catch (Exception ex)
            {
                result.Result = false;
                result.ErrorMsg = ex.Message;
            }

            return result;

            // Find Customer Object
            // if found delete current session and create new session then send it bace to caller
            /*return new AuthenCustomerResultDto
            {
                customerInfo = new CustomerDto
                {
                    CarBrand = "CarBrand",
                    CarColor = "CarColor",
                    CarImg = "CarImg",
                    CarModel = "CarModel",
                    CustImg = "CustImg",
                    InsurancePackage = "Package",
                    LicensePlate = "LicensePlate",
                    Mobile = "Mobile",
                    Name = "Name",
                    Surname = "Surname"
                },
                ErrorMsg = "",
                Result = true,
                SessionId = "qwkoekekeorkweor"
            };*/
        }

        private SessionInfoDto GetSessionId(string sessionId)
        {
            SessionInfoDto result = null;

            // get data by using Licenseplate 
            IService service = new DroidClaim.Service.Service();
            GetAllSessionInfoRequestDto svDto = new GetAllSessionInfoRequestDto();
            svDto.SessionId = sessionId;
            ResponseDto<List<SessionInfoDto>> svResult = service.GetAllSessionInfo(svDto);
            if (!svResult.Status)
            {
                throw new InvalidOperationException("Operation is invalid!");
            }

            List<SessionInfoDto> svDataListDto = svResult.Data;
            if (svDataListDto.Count <= 0)
            {
                throw new Exception("Error : SessionId not found");
            }

            result = svDataListDto[0];
            if (result == null)
            {
                throw new Exception("Invalid return data");
            }

            return result;
        }

        private SessionInfoDto GetSessionId(CustomerDto customer)
        {
            SessionInfoDto result = null;

            // get data by using Licenseplate 
            IService service = new DroidClaim.Service.Service();
            GetAllSessionInfoRequestDto svDto = new GetAllSessionInfoRequestDto();
            svDto.Customer = customer;
            ResponseDto<List<SessionInfoDto>> svResult = service.GetAllSessionInfo(svDto);
            if (!svResult.Status)
            {
                throw new InvalidOperationException("Operation is invalid!");
            }

            List<SessionInfoDto> svDataListDto = svResult.Data;
            if (svDataListDto.Count <= 0)
            {
                throw new Exception("Error : SessionId not found");
            }

            result = svDataListDto[0];
            if (result == null)
            {
                throw new Exception("Invalid return data");
            }

            return result;
        }

        private SessionInfoDto GetSessionId(SurveyorDto surveyor)
        {
            SessionInfoDto result = null;

            // get data by using Licenseplate 
            IService service = new DroidClaim.Service.Service();
            GetAllSessionInfoRequestDto svDto = new GetAllSessionInfoRequestDto();
            svDto.Surveyor = surveyor;
            ResponseDto<List<SessionInfoDto>> svResult = service.GetAllSessionInfo(svDto);
            if (!svResult.Status)
            {
                throw new InvalidOperationException("Operation is invalid!");
            }

            List<SessionInfoDto> svDataListDto = svResult.Data;
            if (svDataListDto.Count <= 0)
            {
                throw new Exception("Error : SessionId not found");
            }

            result = svDataListDto[0];
            if (result == null)
            {
                throw new Exception("Invalid return data");
            }

            return result;
        }
        /*
            public class ClaimRequestDto
            {
                public string SessionId { get; set; }
                public string AccImg { get; set; }
                public double Latitude { get; set; }
                public double Longitude { get; set; }
                public string Location { get; set; }
            }

            public class ClaimRequestResultDto
            {
                public bool Result { get; set; }
                public string ErrorMsg { get; set; }
                public int ClaimInfoId { get; set; }
            }
        */

        public ClaimRequestResultBlDto AddClaimRequest(ClaimRequestBlDto cliamRequest)
        {
            ILog logger = LogManager.GetLogger("Method AddClaimRequest");
            logger.Debug("Input parameters : " + new JavaScriptSerializer().Serialize(cliamRequest));
            // keep Claim Info ลง Database
            // return true if success
            ClaimRequestResultBlDto result = new ClaimRequestResultBlDto();
            result.Result = false;

            try
            {
                // get data by using Licenseplate 
                SessionInfoDto sessionDto = GetSessionId(cliamRequest.SessionId);
                if (sessionDto.Customer == null)
                {
                    throw new Exception("Error Invalid Customer");
                }

                IService service = new DroidClaim.Service.Service();
                ClaimInfoDto svDto = new ClaimInfoDto();
                svDto.AccidentDate = DateTime.Now;
                svDto.AccidentLocation = cliamRequest.Location;
                svDto.Latitude = cliamRequest.Latitude;
                svDto.Longitude = cliamRequest.Longitude;
                svDto.AccImgPath = cliamRequest.AccImg;//ServerFileHandle.WriteImageFile(cliamRequest.AccImg);
                ClaimStatusDto claimStatus = new ClaimStatusDto();
                claimStatus.Id = ClaimStatus.COMPANY_ACCEPTED_STATUS; // Update Status ClaimInfo is Accepted
                svDto.ClaimStatus = claimStatus; 
                svDto.UpdateDate = DateTime.Now;
                 svDto.Customer = sessionDto.Customer;
                ResponseDto<ClaimInfoDto> svResultDto = service.AddClaimInfo(svDto);
                if (!svResultDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }

                ClaimInfoDto svDataDto = svResultDto.Data;
                if (svDataDto == null)
                {
                    throw new Exception("Invalid return data");
                }

                // get all surveyor
                GetAllSurveyorRequestDto dto = new GetAllSurveyorRequestDto();
                SurveyorLocationDto serveyorLocation = new SurveyorLocationDto();
                serveyorLocation.Status = 1;
                dto.SurveyorLocation = serveyorLocation;
                ResponseDto<List<SurveyorDto>> svSorveyorListDto = service.GetAllSurveyor(dto);
                if (!svSorveyorListDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }
                List<SurveyorDto> svSorveyorListDataDto = svSorveyorListDto.Data;
                if (svSorveyorListDataDto == null || svSorveyorListDataDto.Count<=0)
                {
                    throw new Exception("Invalid return data");
                }

                ClosestSurveyor closest = new ClosestSurveyor(svSorveyorListDataDto);
                List<SurveyorDto> svClosestSorveyorList = closest.GetClosest(cliamRequest.Latitude, cliamRequest.Longitude);
                if (svClosestSorveyorList == null || svClosestSorveyorList.Count <= 0)
                {
                    throw new Exception("No seviced surveyor");
                }

                //
                //
                // contact to serveyor to handle claim job 

                var surveyorSession = this.GetSessionId(svClosestSorveyorList[0]);

                GCMServices.Dto.MessageDto message = new GCMServices.Dto.MessageDto();
                message.Code = "sendjob";
                message.MessageJson = "{\"id\":" + svDataDto.Id + "}";
                message.RegistrationId = surveyorSession.RegistrationId;

                GCMServices.IGCMServiceBl gcm = new GCMServices.GCMServiceBl();
                gcm.SendMessage(message);
                //
                //

                result.Result = true;
                result.ErrorMsg = "";
                result.ClaimInfoId = svDataDto.Id;
            }
            catch (Exception ex)
            {
                result.Result = false;
                result.ErrorMsg = ex.Message;
            }

            return result;

            /*return new ClaimRequestResultDto
            {
                ClaimInfoId = 1,
                ErrorMsg = "",
                Result = true
            };*/
        }

        /*
            public class SessionPkDto
            {
                public string LicensePlate { get; set; }
            }
            
            public class AllClaimInfoForCustomerResultDto
            {
                public bool Result { get; set; }
                public String ErrorMsg { get; set; }
                public List<ClaimInfoDto> ClaimInfoList { get; set; }
            }
         
            public class ClaimInfoDto
            {
                public int Id { get; set; }
                public DateTime AccDate { get; set; }
                public string AccidentLocation { get; set; }
                public double Latitude { get; set; }
                public double Longitude { get; set; }
                public DateTime UpdateDate { get; set; }
                public int Status { get; set; }
                public string LicensePlateNo { get; set; }
                public string SurvName { get; set; }
                public string SurvMobile { get; set; }
                public string SurvImg { get; set; }
            }
        */

        public AllClaimInfoForCustomerResultBlDto GetAllClaimInfoForCustomer(SessionPkBlDto sessionPk)
        {
            // get list of Claiminfo of customer
            AllClaimInfoForCustomerResultBlDto result = new AllClaimInfoForCustomerResultBlDto();
            result.Result = false;

            try
            {
                // get data by using Licenseplate 
                SessionInfoDto sessionDto = GetSessionId(sessionPk.SessionId);
                if (sessionDto.Customer == null)
                {
                    throw new Exception("Error Invalid Customer");
                }

                // get data by using Licenseplate 
                GetAllClaimInfoRequestDto svDto = new GetAllClaimInfoRequestDto();
                IService service = new DroidClaim.Service.Service();
                svDto.Customer = sessionDto.Customer;
                ResponseDto<List<ClaimInfoDto>> svResultDto = service.GetAllClaimInfo(svDto);
                if (!svResultDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }

                List<ClaimInfoDto> svDataListDto = svResultDto.Data;
                if (svDataListDto == null)
                {
                    throw new Exception("Invalid return data");
                }

                List<ClaimInfoBlDto> claimInfoBlDto = new List<ClaimInfoBlDto>();
                foreach (ClaimInfoDto svDataDto in svDataListDto)
                {
                    ClaimInfoBlDto blDto = new ClaimInfoBlDto(svDataDto);
                    claimInfoBlDto.Add(blDto);
                }

                result.Result = true;
                result.ErrorMsg = "";
                result.ClaimInfoList = claimInfoBlDto;
            }
            catch (Exception ex)
            {
                result.Result = false;
                result.ErrorMsg = ex.Message;
            }

            return result;
            /*return new List<global::DroidClaimBL.Dto.CustomerDto>
            {
                new global::DroidClaimBL.Dto.CustomerDto{ 
                    AccDate=DateTime.Now,
                    AccidentLocation="AccidentLocation",
                    Id=1,
                    Latitude=13.021233,
                    LicensePlateNo="LicensePlateNo",
                    Longitude=123.023123,
                    Status=1,
                    SurvImg="SurvImg",
                    SurvMobile="SurvMobile",
                    SurvName="SurvName",
                    UpdateDate=DateTime.Now
                },
                new global::DroidClaimBL.Dto.CustomerDto{ 
                    AccDate=DateTime.Now,
                    AccidentLocation="AccidentLocation2",
                    Id=1,
                    Latitude=13.021233,
                    LicensePlateNo="LicensePlateNo2",
                    Longitude=123.023123,
                    Status=1,
                    SurvImg="SurvImg2",
                    SurvMobile="SurvMobile2",
                    SurvName="SurvName2",
                    UpdateDate=DateTime.Now
                }
            };*/
        }

        /*
            public class SessionPkDto
            {
                public string LicensePlate { get; set; }
            }
        */

        public bool Logout(SessionPkBlDto sessionPk)
        {
            bool result = false;

            try
            {
                SessionInfoDto sessionInfo = GetSessionId(sessionPk.SessionId);
                IService service = new DroidClaim.Service.Service();
                List<string> idList = new List<string>();
                idList.Add(sessionInfo.SessionId);
                service.DeleteSessionInfo(idList);

                result = true;
            }
            catch (Exception ex)
            {
                result = false;
            }

            return result;
            /*logger = LogManager.GetLogger("/Logout");
            logger.Debug("Input parameters LicensePlate : " + SessionPk.LicensePlate);
            if (SessionPk.LicensePlate == "123")
                return true;
            else
                return false;*/
        }

        //
        // Surveryor
        //

        public ResultBlDto RegisterSurveyor(RegisterSurveyorBlDto blDto)
        {
            ResultBlDto result = new ResultBlDto();
            result.Result = false;
            try
            {
                Service.Dto.SurveyorDto svDto = blDto.ToServiceDto();
                var deriveBytes = new Rfc2898DeriveBytes(svDto.Password, 20);
                byte[] salt = deriveBytes.Salt;
                byte[] key = deriveBytes.GetBytes(20);
                svDto.Salt = Convert.ToBase64String(salt);
                svDto.Password = Convert.ToBase64String(key);

                IService dcService = new DroidClaim.Service.Service();
                SurveyorLocationDto svLocationDto = new SurveyorLocationDto();
                svLocationDto.Longitude = svDto.SurveyorLocation.Longitude;
                svLocationDto.Latitude = svDto.SurveyorLocation.Latitude;
                svLocationDto.Status = svDto.SurveyorLocation.Status;
                ResponseDto<SurveyorLocationDto> svLocationResult = dcService.AddSurveyorLocation(svLocationDto);
                if (!svLocationResult.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }
                if (svLocationResult.Data == null)
                {
                    throw new Exception("Error null Data");
                }
                svDto.SurveyorLocation.Id = svLocationResult.Data.Id;
                ResponseDto<SurveyorDto> svAddResult = dcService.AddSurveyor(svDto);
                if (!svAddResult.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }

                result.Result = true;
            }
            catch (Exception ex)
            {
                result.Result = false;
                result.ErrorMsg = ex.Message;
            }

            return result;
        }

        /*
        public class AuthenSurveyorDto
        {
            public string Username { get; set; }
            public string Password { get; set; }
            public bool noSurveyorData { get; set; }
            public String RregistrationId { get; set; }
        }

        public class AuthenSurveyorResultDto
        {
            public bool Result { get; set; }
            public string ErrorMsg { get; set; }
            public string SessionId { get; set; }
            public SurveyorDto SurveyorInfo { get; set; }
        }
        */
        public AuthenSurveyorResultBlDto AuthenSurveyor(AuthenSurveyorBlDto authenSurveyor)
        {
            AuthenSurveyorResultBlDto result = new AuthenSurveyorResultBlDto();
            result.Result = false;

            try
            {
                // get data by using Username
                IService service = new DroidClaim.Service.Service();
                GetAllSurveyorRequestDto svDto = new GetAllSurveyorRequestDto();
                svDto.Username = authenSurveyor.Username;
                ResponseDto<List<Service.Dto.SurveyorDto>> svResultDto = service.GetAllSurveyor(svDto);
                if (!svResultDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid.");
                }

                // Validate result's data is not error
                List<Service.Dto.SurveyorDto> svDataListDto = svResultDto.Data;
                if (svDataListDto.Count <= 0)
                {
                    throw new Exception("Username or Password is invalid.");
                }
                Service.Dto.SurveyorDto svDataDto = svDataListDto[0];
                if (svDataDto == null)
                {
                    throw new Exception("Invalid return data");
                }

                // do authenticate whether it is correct or not
                byte[] saltByte = Convert.FromBase64String(svDataDto.Salt);
                var deriveBytes = new Rfc2898DeriveBytes(authenSurveyor.Password, saltByte);
                byte[] inputPassByte = deriveBytes.GetBytes(20);  // derive a 20-byte key
                byte[] userPassByte = Convert.FromBase64String(svDataDto.Password);
                if (!userPassByte.SequenceEqual(inputPassByte))
                {
                    throw new InvalidOperationException("Username or Password is invalid!");
                }

                // delete invalidate seesion of this Surveyor
                GetAllSessionInfoRequestDto svGetSessionDto = new GetAllSessionInfoRequestDto();
                svGetSessionDto.Surveyor = svDataDto;
                ResponseDto<List<SessionInfoDto>> svResultGetSessionDto = service.GetAllSessionInfo(svGetSessionDto);
                if (!svResultGetSessionDto.Status)
                {
                    throw new InvalidOperationException("Operation Error");
                }
                List<SessionInfoDto> sessionList = svResultGetSessionDto.Data;
                if (sessionList == null)
                {
                    throw new InvalidOperationException("Data Error");
                }
                if (sessionList.Count > 0)
                {
                    List<string> idList = new List<string>();
                    foreach (SessionInfoDto session in sessionList)
                    {
                        idList.Add(session.SessionId);
                    }
                    service.DeleteSessionInfo(idList);
                }

                // it's ok, so create session
                SessionInfoDto sessionInfo = new SessionInfoDto();
                sessionInfo.UpdateTime = DateTime.Now;
                sessionInfo.SessionId = Guid.NewGuid().ToString();
                sessionInfo.Surveyor = svDataDto;
                sessionInfo.Customer = null;
                sessionInfo.RegistrationId = authenSurveyor.RegistrationId;
                service.AddSessionInfo(sessionInfo);

                // return result to customer
                result.Result = true;
                result.ErrorMsg = "";
                result.SessionId = sessionInfo.SessionId;
                result.SurveyorInfo = null;
                if (authenSurveyor.NoSurveyorData)
                {
                    result.SurveyorInfo = new SurveyorBlDto(svDataDto);
                }
            }
            catch (Exception ex)
            {
                result.Result = false;
                result.ErrorMsg = ex.Message;
            }

            return result;
        }

        /*
        public class SurveyorStatusDto
        {
            public string SessionId { get; set; }
            public bool Status { get; set; }
            public double Latitude { get; set; }
            public double Longitude { get; set; }
        }

        public class UpdateSurveyorStatusResultDto
        {
            public bool Result { get; set; }
            public string ErrorMsg { get; set; }
        }
        */
        public UpdateSurveyorStatusResultBlDto UpdateSurveyorStatus(SurveyorStatusBlDto status)
        {
            UpdateSurveyorStatusResultBlDto result = new UpdateSurveyorStatusResultBlDto();
            result.Result = false;

            try
            {
                SessionInfoDto sessionInfo = GetSessionId(status.SessionId);
                SurveyorDto surveyor = sessionInfo.Surveyor;
                if (surveyor == null)
                {
                    throw new Exception("Invalid User");
                }

                if (surveyor.SurveyorLocation == null)
                {
                    surveyor.SurveyorLocation = new SurveyorLocationDto();
                    
                }

                bool isUpdateSurveyor = false;
                if (surveyor.SurveyorLocation.Id <= 0)
                {
                    isUpdateSurveyor = true;
                }

                // update SurveyorLocation Table
                IService service = new DroidClaim.Service.Service();
                SurveyorLocationDto svDto = surveyor.SurveyorLocation;
                //svDto.Id = surveyor.SurveyorLocation.Id;
                svDto.Status = status.Status==true?1:0;
                svDto.Latitude = status.Latitude;
                svDto.Longitude = status.Longitude;
                ResponseDto<SurveyorLocationDto> slResultDto = service.UpdateSurveyorLocation(svDto);
                if (!slResultDto.Status)
                {
                    throw new Exception("Error Updating SurveyorLocation");
                }

                if (isUpdateSurveyor)
                {
                    ResponseDto<SurveyorDto> svResultDto = service.UpdateSurveyor(surveyor);
                    if (!svResultDto.Status)
                    {
                        throw new Exception("Error Updating Surveyor");
                    }
                }

                result.Result = slResultDto.Status;
                result.ErrorMsg = "";
            }
            catch (Exception ex)
            {
                result.Result = false;
                result.ErrorMsg = ex.Message;
            }

            return result;
        }

        /*
        public class SurveyorLocationDto
        {
            public string SessionId { get; set; }
            public bool Status { get; set; }
            public double Latitude { get; set; }
            public double Longitude { get; set; }
        }

        public class UpdateSurveyorLocationResultDto
        {
            public bool Result { get; set; }
            public string ErrorMsg { get; set; }
        }
        */
        public UpdateSurveyorLocationResultBlDto UpdateSurveyorLocation(SurveyorLocationBlDto status)
        {
            UpdateSurveyorLocationResultBlDto result = new UpdateSurveyorLocationResultBlDto();
            result.Result = false;

            try
            {
                SessionInfoDto sessionInfo = GetSessionId(status.SessionId);
                SurveyorDto surveyor = sessionInfo.Surveyor;
                if (surveyor == null)
                {
                    throw new Exception("Invalid User");
                }

                if (surveyor.SurveyorLocation == null)
                {
                    surveyor.SurveyorLocation = new SurveyorLocationDto();
                }

                bool isUpdateSurveyor = false;
                if (surveyor.SurveyorLocation.Id <=0)
                {
                    isUpdateSurveyor = true;
                }

                // update SurveyorLocation Table
                IService service = new DroidClaim.Service.Service();
                SurveyorLocationDto svDto = surveyor.SurveyorLocation;
                svDto.Status = status.Status==true?1:0;
                svDto.Latitude = status.Latitude;
                svDto.Longitude = status.Longitude;
                ResponseDto<SurveyorLocationDto> slResultDto = service.UpdateSurveyorLocation(svDto);
                if (!slResultDto.Status)
                {
                    throw new Exception("Error SurveyorLocation");
                }

                if (isUpdateSurveyor)
                {
                    ResponseDto<SurveyorDto> svResultDto = service.UpdateSurveyor(surveyor);
                    if (!svResultDto.Status)
                    {
                        throw new Exception("Error Updating Surveyor");
                    }
                }

                result.Result = slResultDto.Status;
                result.ErrorMsg = "";

                // get accept claim info
                GetAllClaimInfoRequestDto svClimInfoDto = new GetAllClaimInfoRequestDto();
                svClimInfoDto.Surveyor = surveyor;
                ResponseDto<List<ClaimInfoDto>> svResultClaimInfoDto = service.GetAllClaimInfo(svClimInfoDto);
                if (!svResultClaimInfoDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }

                List<ClaimInfoDto> svCliamInfoListDto = svResultClaimInfoDto.Data;
                if (svCliamInfoListDto == null || svCliamInfoListDto.Count <= 0)
                {
                    throw new Exception("Invalid return data");
                }

                ClaimInfoDto acceptClaimInfo = null;
                foreach (ClaimInfoDto dto in svCliamInfoListDto)
                {
                    if (dto.ClaimStatus == null)
                    {
                        break;
                    }

                    if (dto.ClaimStatus.Id == ClaimStatus.SURVEYOR_ACCEPTED_STATUS)
                    {
                        acceptClaimInfo = dto;
                        break;
                    }
                }

                if (acceptClaimInfo != null)
                {
                    SessionInfoDto custSessionInfo = GetSessionId(acceptClaimInfo.Customer);
                    GCMServices.Dto.MessageDto message = new GCMServices.Dto.MessageDto();
                    message.Code = "map";
                    message.MessageJson = "{\"lat\":" + svDto.Latitude + ",\"lng\":" + svDto.Longitude + "}";
                    message.RegistrationId = custSessionInfo.RegistrationId;

                    GCMServices.IGCMServiceBl gcm = new GCMServices.GCMServiceBl();
                    gcm.SendMessage(message);
                }
            }
            catch (Exception ex)
            {
                result.Result = false;
                result.ErrorMsg = ex.Message;
            }

            return result;
        }

        /*
            public class ClaimInfoPKDto
            {
                public string SessionId { get; set; }
                public int Id { get; set; }
            }

            public class SurveyorLocationResultDto
            {
                public bool Result { get; set; }
                public string ErrorMsg { get; set; }
                public double Latitude { get; set; }
                public double Longitude { get; set; }
                public bool Status { get; set; }
            }
        */
        public SurveyorLocationResultBlDto GetSurveyorLocation(ClaimInfoPKBlDto cliamInfoPk)
        {
            SurveyorLocationResultBlDto result = new SurveyorLocationResultBlDto();
            result.Result = false;

            try
            {
                SessionInfoDto sessionInfo = GetSessionId(cliamInfoPk.SessionId);
                SurveyorDto surveyor = sessionInfo.Surveyor;

                // get data by using Licenseplate 
                IService service = new DroidClaim.Service.Service();
                GetAllSurveyorRequestDto svDto = new GetAllSurveyorRequestDto();
                svDto.SurveyerId = surveyor.SurveyerId;
                ResponseDto<List<SurveyorDto>> svResultDto = service.GetAllSurveyor(svDto);
                if (!svResultDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }

                List<SurveyorDto> svDataListDto = svResultDto.Data;
                if (svDataListDto.Count <= 0)
                {
                    throw new Exception("Error : SessionId not found");
                }

                SurveyorDto svDataDto = svDataListDto[0];
                if (svDataDto == null)
                {
                    throw new Exception("Invalid return data");
                }

                result.Result = true;
                result.ErrorMsg = "";
                result.Latitude = svDataDto.SurveyorLocation.Latitude;
                result.Longitude = svDataDto.SurveyorLocation.Longitude;
                result.Status = svDataDto.SurveyorLocation.Status==1?true:false;
            }
            catch (Exception ex)
            {
                result.Result = false;
                result.ErrorMsg = ex.Message;
            }

            return result;
        }

        /*
        public class ClaimInfoPKDto
        {
            string SessionId { get; set; }
            int Id { get; set; }
        }
        public class ClaimInfoForSurveyorResultDto
        {
            public string LicensePlate { get; set; }
            public string CustName { get; set; }
            public string CarDetail { get; set; }
            public string CustMobile { get; set; }
            public string CarImage { get; set; }
            public DateTime AccidentDate { get; set; }
            public string AccidentLocation { get; set; }
            public double AccidentLatitude { get; set; }
            public double AccidentLongitude { get; set; }
            }
         */
        public ClaimInfoForSurveyorResultBlDto GetClaimInfoForSurveyor(ClaimInfoPKBlDto claimInfoPK)
        {
            ClaimInfoForSurveyorResultBlDto result = new ClaimInfoForSurveyorResultBlDto();
            result.LicensePlate = "";

            try
            {
                // get data by using Licenseplate 
                SessionInfoDto sessionDto = GetSessionId(claimInfoPK.SessionId);
                if (sessionDto.Surveyor == null)
                {
                    throw new Exception("Error Invalid Surveryor");
                }

                // get data by using Licenseplate 
                IService service = new DroidClaim.Service.Service();
                GetAllClaimInfoRequestDto svDto = new GetAllClaimInfoRequestDto();
                svDto.Id = claimInfoPK.Id;
                ResponseDto<List<ClaimInfoDto>> svResultDto = service.GetAllClaimInfo(svDto);
                if (!svResultDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }

                List<ClaimInfoDto> svDataListDto = svResultDto.Data;
                if (svDataListDto == null || svDataListDto.Count <= 0)
                {
                    throw new Exception("Invalid return data");
                }

                ClaimInfoDto svDataDto = svDataListDto[0];
                if (svDataDto.Customer != null)
                {
                    result.LicensePlate = svDataDto.Customer.LicensePlate;
                    result.CustName = svDataDto.Customer.NameString;
                    result.CarDetail = svDataDto.Customer.CarModelString;
                    result.CustMobile = svDataDto.Customer.Mobile;
                    result.CarImage = ServerFileHandle.GetImageString(svDataDto.Customer.CarImgPath);
                }

                result.AccidentDate = svDataDto.AccidentDate;
                result.AccidentLocation = svDataDto.AccidentLocation;
                result.AccidentLatitude = svDataDto.Latitude;
                result.AccidentLongitude = svDataDto.Longitude;
            }
            catch (Exception ex)
            {
                result.LicensePlate = "";
            }

            return result;
        }

        /*
            public class ClaimInfoPKDto
            {
                public string SessionId { get; set; }
                public int Id { get; set; }
            }
            public class ClaimInfoForCustomerResultDto
            {
                public String LicensePlate { get; set; }
                public String CustName { get; set; }
                public String CarDetail { get; set; }
                public String SurveyorMobile { get; set; }
                public String SurveyorId { get; set; }
                public String SurveyorName { get; set; }
                public String SurveyorImg { get; set; }
                public int Status { get; set; }
            }
        */
        public ClaimInfoForCustomerResultBlDto GetClaimInfoForCustomer(ClaimInfoPKBlDto claimInfoPK)
        {
            ClaimInfoForCustomerResultBlDto result = new ClaimInfoForCustomerResultBlDto();
            result.LicensePlate = "";

            try
            {
                // get data by using Licenseplate 
                SessionInfoDto sessionDto = GetSessionId(claimInfoPK.SessionId);
                if (sessionDto.Customer == null)
                {
                    throw new Exception("Error Invalid Customer");
                }

                // get data by using Licenseplate 
                IService service = new DroidClaim.Service.Service();
                GetAllClaimInfoRequestDto svDto = new GetAllClaimInfoRequestDto();
                svDto.Id = claimInfoPK.Id;
                ResponseDto<List<ClaimInfoDto>> svResultDto = service.GetAllClaimInfo(svDto);
                if (!svResultDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }

                List<ClaimInfoDto> svDataListDto = svResultDto.Data;
                if (svDataListDto == null || svDataListDto.Count<=0)
                {
                    throw new Exception("Invalid return data");
                }

                ClaimInfoDto svDataDto = svDataListDto[0];
                if(svDataDto.Customer!=null){
                    result.LicensePlate = svDataDto.Customer.LicensePlate;
                    result.CustName = svDataDto.Customer.NameString;
                    result.CarDetail = svDataDto.Customer.CarModelString;
                }
                
                if(svDataDto.Surveyor!=null){
                    result.SurveyorMobile = svDataDto.Surveyor.Mobile;
                    result.SurveyorId = svDataDto.Surveyor.SurveyerId;
                    result.SurveyorName = svDataDto.Surveyor.Name + " " + svDataDto.Surveyor.Surname;
                    result.SurveyorImg = ServerFileHandle.GetImageString(svDataDto.Surveyor.PicturePath);
                }

                result.Status = svDataDto.ClaimStatus.Id;
            }
            catch (Exception ex)
            {
                result.LicensePlate = "";
            }

            return result;
        }

        public AcceptMessageResultBlDto SendAcceptMessage(AcceptMessageBlDto acceptMessage)
        {
            AcceptMessageResultBlDto result = new AcceptMessageResultBlDto();
            result.Result = false;

            try
            {
                // get data by using Licenseplate 
                SessionInfoDto sessionDto = GetSessionId(acceptMessage.SessionId);
                if (sessionDto.Surveyor == null)
                {
                    throw new Exception("Error Invalid Surveryor");
                }

                IService service = new DroidClaim.Service.Service();
                // get claim info
                GetAllClaimInfoRequestDto svClimInfoDto = new GetAllClaimInfoRequestDto();
                svClimInfoDto.Id = acceptMessage.ClaimId;
                ResponseDto<List<ClaimInfoDto>> svResultClaimInfoDto = service.GetAllClaimInfo(svClimInfoDto);
                if (!svResultClaimInfoDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }

                List<ClaimInfoDto> svCliamInfoListDto = svResultClaimInfoDto.Data;
                if (svCliamInfoListDto == null || svCliamInfoListDto.Count <= 0)
                {
                    throw new Exception("Invalid return data");
                }

                ClaimInfoDto claimInfoDto = svCliamInfoListDto[0];
                ClaimStatusDto claimStatus = new ClaimStatusDto();
                claimStatus.Id = ClaimStatus.SURVEYOR_ACCEPTED_STATUS;
                claimInfoDto.ClaimStatus = claimStatus;
                claimInfoDto.Surveyor = sessionDto.Surveyor;
                claimInfoDto.UpdateDate = DateTime.Now;
                ResponseDto<ClaimInfoDto> svResultDto = service.UpdateClaimInfo(claimInfoDto);
                if (!svResultDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }
                // Send message to customer
                GetAllSessionInfoRequestDto sessionInfoRequest = new GetAllSessionInfoRequestDto();
                sessionInfoRequest.Customer = new CustomerDto();
                sessionInfoRequest.Customer.LicensePlate = claimInfoDto.Customer.LicensePlate;
                ResponseDto<List<SessionInfoDto>> svSessionResultDto = service.GetAllSessionInfo(sessionInfoRequest);
                if (!svSessionResultDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }
                if(svSessionResultDto.Data==null||svSessionResultDto.Data.Count<=0)
                {
                    throw new InvalidOperationException("Data is invalid!");
                }

                GCMServices.Dto.MessageDto message = new GCMServices.Dto.MessageDto();
                message.Code = "acceptjob";
                message.MessageJson = "{\"id\":" + claimInfoDto.Id + "}";
                message.RegistrationId = svSessionResultDto.Data[0].RegistrationId;

                GCMServices.IGCMServiceBl gcm = new GCMServices.GCMServiceBl();
                gcm.SendMessage(message);


                result.Result = svResultDto.Status;
                result.ErrorMsg = svResultDto.ErrorMessage;
            }
            catch (Exception ex)
            {
                result.Result = false;
                result.ErrorMsg = ex.Message;
            }

            return result;
        }

        /*
        public class DenyMessageDto
        {
            public String SessionId { get; set; }
            public int ClaimId { get; set; }
            public String DenyReason { get; set; }
        }
        public class DenyMessageResultDto
        {
            public bool Result { get; set; }
            public string ErrorMsg { get; set; }
        }
        */
        public DenyMessageResultBlDto SendDenyMessage(DenyMessageBlDto denyMessage)
        {
            DenyMessageResultBlDto result = new DenyMessageResultBlDto();
            result.Result = false;

            try
            {
                // get data by using Licenseplate 
                SessionInfoDto sessionDto = GetSessionId(denyMessage.SessionId);
                if (sessionDto.Surveyor == null)
                {
                    throw new Exception("Error Invalid Surveryor");
                }

                IService service = new DroidClaim.Service.Service();
                // get claim info
                GetAllClaimInfoRequestDto svClimInfoDto = new GetAllClaimInfoRequestDto();
                svClimInfoDto.Id = denyMessage.ClaimId;
                ResponseDto<List<ClaimInfoDto>> svResultClaimInfoDto = service.GetAllClaimInfo(svClimInfoDto);
                if (!svResultClaimInfoDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }

                List<ClaimInfoDto> svCliamInfoListDto = svResultClaimInfoDto.Data;
                if (svCliamInfoListDto == null || svCliamInfoListDto.Count<=0)
                {
                    throw new Exception("Invalid return data");
                }

                ClaimInfoDto claimInfoDto = svCliamInfoListDto[0];


                RejectedHistoryDto svDto = new RejectedHistoryDto();
                svDto.Reason = denyMessage.DenyReason;
                svDto.ClaimInfo = claimInfoDto;
                svDto.Surveyor = sessionDto.Surveyor;
                ResponseDto<RejectedHistoryDto> svResultDto = service.AddRejectedHistory(svDto);
                if (!svResultDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }

                result.Result = svResultDto.Status;
                result.ErrorMsg = svResultDto.ErrorMessage;
            }
            catch (Exception ex)
            {
                result.Result = false;
                result.ErrorMsg = ex.Message;
            }

            return result;
        }
        /*
        public class UpdateClaimInfoDto
        {
            public string SessionId { get; set; }
            public int ClaimId { get; set; }
            public string ClaimDocImage { get; set; }
        }
        public class ClaimIdResultDto
        {
            public int ClaimNumber { get; set; }
            public string ErrorMsg { get; set; }
        }*/
        public ClaimIdResultBlDto UpdateClaim(UpdateClaimInfoBlDto updateClaimInfo)
        {
            ClaimIdResultBlDto result = new ClaimIdResultBlDto();
            result.ClaimNumber = -1;

            try
            {
                // get data by using Licenseplate 
                SessionInfoDto sessionDto = GetSessionId(updateClaimInfo.SessionId);
                if (sessionDto.Surveyor == null)
                {
                    throw new Exception("Error Invalid Surveryor");
                }

                // get data by using Licenseplate 
                IService service = new DroidClaim.Service.Service();
                CliamDocDto svClimDocDto = new CliamDocDto();
                //svClimDocDto.CliamDocImgPath = ServerFileHandle.WriteImageFile(updateClaimInfo.ClaimDocImage);
                svClimDocDto.CliamDocImgPath = updateClaimInfo.ClaimDocImage;
                ResponseDto<CliamDocDto> svResultClaimInfoDto = service.AddCliamDoc(svClimDocDto);
                if (!svResultClaimInfoDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }

                CliamDocDto svCliamDocDto = svResultClaimInfoDto.Data;
                if (svCliamDocDto == null)
                {
                    throw new Exception("Invalid return data");
                }

                GetAllClaimInfoRequestDto svClaimInfoDto = new GetAllClaimInfoRequestDto();
                svClaimInfoDto.Id = updateClaimInfo.ClaimId;
                ResponseDto<List<ClaimInfoDto>> svResultDto = service.GetAllClaimInfo(svClaimInfoDto);
                if (!svResultDto.Status)
                {
                    throw new InvalidOperationException("Operation is invalid!");
                }

                List<ClaimInfoDto> svDataListDto = svResultDto.Data;
                if (svDataListDto == null || svDataListDto.Count <= 0)
                {
                    throw new Exception("Invalid return data");
                }

                ClaimInfoDto svDataDto = svDataListDto[0];
                svDataDto.CliamDoc = svCliamDocDto;
                svDataDto.UpdateDate = DateTime.Now;
                svDataDto.ClaimStatus.Id = ClaimStatus.RECEICE_CLAIMDOC_STAUS;
                ResponseDto<ClaimInfoDto> svResult = service.UpdateClaimInfo(svDataDto);
                if (!svResult.Status)
                {
                    throw new Exception("Error Updating");
                }

                //Send GCM
                var customerSessionInfo = this.GetSessionId(svClaimInfoDto.Customer);
                GCMServices.Dto.MessageDto message = new GCMServices.Dto.MessageDto();
                message.Code = "updatejob";
                message.MessageJson = "{\"id\":" + svClaimInfoDto.Id + "}";
                message.RegistrationId = customerSessionInfo.RegistrationId;
                GCMServices.IGCMServiceBl gcm = new GCMServices.GCMServiceBl();
                gcm.SendMessage(message);


                result.ClaimNumber = svCliamDocDto.Id;
                result.ErrorMsg = "";
            }
            catch (Exception ex)
            {
                result.ClaimNumber = -1;
                result.ErrorMsg = ex.Message;
            }

            return result;
        }

        // for test
        public global::DroidClaimBL.Dto.CustomerBlDto GetCustomer()
        {
            logger = LogManager.GetLogger("/GetCustomer");
            logger.Info("GetCustomer ");
            return new global::DroidClaimBL.Dto.CustomerBlDto
            {
                CarBrand = "CarBrand",
                CarColor = "CarColor",
                CarImg = "CarImg",
                CarModel = "CarModel",
                CustImg = "CustImg",
                InsurancePackage = "Package",
                LicensePlate = "LicensePlate",
                Mobile = "Mobile",
                Name = "Name",
                Surname = "Surname"
            };
        }
    }
}
